package org.jiuling.kuaidi100;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.jiuling.basics.converter.StringConvert;
import org.jiuling.basics.enums.HttpResponseStatusEnum;
import org.jiuling.basics.exception.BasicsException;
import org.jiuling.basics.util.EnumUtil;
import org.jiuling.basics.validation.ObjectVerify;
import org.jiuling.basics.validation.StringVerify;
import org.jiuling.crypto.algorithm.MD5;
import org.jiuling.kuaidi100.config.Kuaidi100Config;
import org.jiuling.kuaidi100.config.enums.Kuaidi100ApiEnum;
import org.jiuling.kuaidi100.dto.ExpressInfoPushDto;
import org.jiuling.kuaidi100.dto.RealTimeExpressCheckDto;
import org.jiuling.kuaidi100.dto.SubscribeExpressInfoPushDto;
import org.jiuling.kuaidi100.exception.Kuaidi100RuntimeException;
import org.jiuling.kuaidi100.model.RealTimeExpressCheckModel;
import org.jiuling.kuaidi100.model.enums.ExpressStateEnum;
import org.jiuling.request.http.HttpRequest;
import org.jiuling.request.http.factory.HttpRequestFactory;
import org.jiuling.request.http.model.HttpRequestHeader;
import org.jiuling.request.http.model.HttpRequestParam;
import org.jiuling.request.http.model.HttpResponse;

import java.io.IOException;
import java.util.Objects;


/**
 * 快递查询
 * @author 紫灵
 * @date 2024年02月27日 23时19分30秒
 */
public class ExpressCheck {

    /** 快递100配置 */
    private final Kuaidi100Config kuaidi100Config;

    public ExpressCheck(Kuaidi100Config kuaidi100Config) {
        this.kuaidi100Config = kuaidi100Config;
    }

    /**
     * 实时快递查询
     * @param realTimeExpressCheckDto 实时快递查询数据传输对象
     * @return 实时快递查询模型
     */
    public RealTimeExpressCheckModel realTimeExpressCheck(RealTimeExpressCheckDto realTimeExpressCheckDto){
        // 实时快递查询Api
        Kuaidi100ApiEnum kuaidi100ApiEnum = Kuaidi100ApiEnum.REAL_TIM_EXPRESS_CHECK;

        // 封装数据
        String realTimeExpressCheckDtoJsonString = JSON.toJSONString(realTimeExpressCheckDto);
        try {
            // 开启HTTP请求
            HttpRequest httpRequest = HttpRequestFactory.openHttpRequest(kuaidi100ApiEnum.getUrl());
            httpRequest.setHttpRequestHeader(
                    new HttpRequestHeader().add("Content-Type","application/x-www-form-urlencoded")
            );

            String customer = kuaidi100Config.getCustomer();
            httpRequest.setHttpRequestParam(
                    new HttpRequestParam()
                            .add("customer",customer)
                            .add("param",realTimeExpressCheckDtoJsonString)
                            .add("sign", StringConvert.toUpperCase(MD5.getMd5(realTimeExpressCheckDtoJsonString+kuaidi100Config.getKey()+customer)))
            );
            JSONObject realTimeExpressCheckJson = JSON.parseObject(getHttpRequestResponseBody(httpRequest.send()));
            if(!ObjectVerify.isNull(realTimeExpressCheckJson.getString("returnCode"))){
                throw new Kuaidi100RuntimeException(realTimeExpressCheckJson.getString("message"));
            }

            return RealTimeExpressCheckModel.builder()
                    .addMessage(realTimeExpressCheckJson.getString("message"))
                    .addNu(realTimeExpressCheckJson.getString("nu"))
                    .addIscheck(realTimeExpressCheckJson.getString("ischeck"))
                    .addCondition(realTimeExpressCheckJson.getString("condition"))
                    .addCom(realTimeExpressCheckJson.getString("com"))
                    .addStatus(realTimeExpressCheckJson.getString("status"))
                    .addState(EnumUtil.valueOfEnum(ExpressStateEnum.class,realTimeExpressCheckJson.getInteger("state"),"getValue").getName())
                    // 封装数据
                    .addDataList(realTimeExpressCheckJson.getJSONArray("data").stream().map(dataJsonArray ->{
                        JSONObject dataJson = JSON.parseObject(dataJsonArray.toString());
                        if(ObjectVerify.isNull(dataJson)) {
                            return null;
                        }
                        return RealTimeExpressCheckModel.DataModel.builder()
                                .addTime(dataJson.getString("time"))
                                .addFtime(dataJson.getString("ftime"))
                                .addContext(dataJson.getString("context"))
                                .addStatus(dataJson.getString("status"))
                                .addStatusCode(dataJson.getString("statusCode"))
                                .addAreaCode(dataJson.getString("areaCode"))
                                .addAreaName(dataJson.getString("areaName"))
                                .addAreaName(dataJson.getString("areaCenter"))
                                .addLocation(dataJson.getString("location"))
                                .addAreaPinYin(dataJson.getString("areaPinYin"))
                                .build();
                    }).toList())
                    .build();

        } catch ( IOException | BasicsException e) {
            throw new Kuaidi100RuntimeException(e);
        }
    }

    /**
     * 订阅快递信息推送
     * @param subscribeExpressInfoPushDto 订阅快递信息推送数据传输对象
     * @return 是否订阅成功
     */
    public boolean subscribeExpressInfoPush(SubscribeExpressInfoPushDto subscribeExpressInfoPushDto){
        // 快递信息推送Api
        Kuaidi100ApiEnum kuaidi100ApiEnum = Kuaidi100ApiEnum.EXPRESS_INFO_PUSH;
        // 封装数据
        String subscribeExpressInfoPushDtoParamJsonString = JSON.toJSONString(subscribeExpressInfoPushDto.getParam());
        try {
            // 开启Http请求
            HttpRequest httpRequest = HttpRequestFactory.openHttpRequest(kuaidi100ApiEnum.getUrl());
            httpRequest.setHttpRequestHeader(
                    new HttpRequestHeader()
                            .add("Content-Type","application/x-www-form-urlencoded")
            );
            httpRequest.setHttpRequestParam(
                    new HttpRequestParam()
                            .add("schema",subscribeExpressInfoPushDto.getSchema())
                            .add("param",subscribeExpressInfoPushDtoParamJsonString)
            );
            JSONObject subscribeExpressInfoPushjson = JSON.parseObject(getHttpRequestResponseBody(httpRequest.send()));
            if(subscribeExpressInfoPushjson.getInteger("returnCode") != 200){
                throw new Kuaidi100RuntimeException(subscribeExpressInfoPushjson.getString("message"));
            }
            return true;
        } catch (IOException e) {
            throw new Kuaidi100RuntimeException(e);
        }
    }

    /**
     * 物流信息推送
     * @param sign 签名
     * @param param 参数
     * @param salt 盐值
     * @return 快递信息推送数据传输对象
     */
    public ExpressInfoPushDto expressInfoPush(String sign,ExpressInfoPushDto param,String salt){
        if(!StringVerify.isBlank(salt)){
            if(!Objects.equals(sign, StringConvert.toUpperCase(MD5.getMd5(param + salt)))){
                throw new Kuaidi100RuntimeException("数据验证失败！");
            }
        }
        return param;
    }

    /**
     * 获取请求响应内容
     * @param httpResponse http请求响应
     * @return 请求响应内容
     */
    private String getHttpRequestResponseBody(HttpResponse httpResponse){
        if(httpResponse.getHttpResponseStatus() != HttpResponseStatusEnum.OK){
            throw new Kuaidi100RuntimeException(httpResponse.getErrorBody());
        }
        return httpResponse.getBody();
    }

}
